import django_filters
import django_filters.rest_framework
from django.db.models import Q
from django_filters.rest_framework import FilterSet, DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.views import APIView

from keep.tools import audit_workflow, set_audit, audit_agree
# from keep.tools import add_task, get_agent_tools
from tools.myjwt import MJwt
from keep.models import Resource, Role, StaffModel, Resource_exp, PersonModel, WorkflowPermission, Workflow, \
    WorkflowApprovalNode, Department, Position, Task, Approval_Record
from keep.seriali import ResourceSerializer, RoleSerializer, StaffSerializer, Resource_expSerializer, \
    Person_infoSerializer, WorkflowPermission_Ser, WorkFlowSerializer, WorkflowApprovalNodeSerializer, \
    DepartmentSerializer, PositionSerializer, TaskSerializer, Approval_RecordSerializer


# Create your views here.
class ResourceFilter(FilterSet):
    pid = django_filters.rest_framework.CharFilter(field_name='pid')
    name = django_filters.rest_framework.CharFilter(field_name='name')
    class Meta:
        model = Resource
        fields = ['pid','name']
class ResourcePage(PageNumberPagination):
    page_size = 6
    page_size_query_param = 'size'
    page_query_param = 'page'


class ResourceViewSet(viewsets.ModelViewSet):
    queryset = Resource.objects.all()
    serializer_class = ResourceSerializer
    pagination_class = ResourcePage
    filter_backends = [DjangoFilterBackend]
    filterset_class = ResourceFilter

    @action(detail=False, methods=['get'])
    def get_pid_notnull(self, request):
        data = Resource.objects.filter(pid__isnull=False)
        ser = ResourceSerializer(data, many=True)
        return Response({"code": 200, "msg": "查询子类数据成功", "data": ser.data})

    @action(detail=False, methods=['get'])
    def get_pid_null(self, request):
        data = Resource.objects.filter(pid__isnull=True)
        ser = ResourceSerializer(data, many=True)
        return Response({"code": 200, "msg": "查询父类数据成功", "data": ser.data})

    @action(methods=['post'], detail=False)
    def add_resource(self, request, *args, **kwargs):
        data = request.data.get('resource')
        print(data)

        # 获取父资源实例
        parent_resource = None
        if data['pid']:
            try:
                parent_resource = Resource.objects.get(id=data['pid'])
            except Resource.DoesNotExist:
                return Response({'msg': '父资源不存在'}, status=400)

        # 创建数据
        Resource.objects.create(
            name=data['name'],
            url=data['url'],
            pid=parent_resource
        )

        return Response({'msg': '添加成功'})

    @action(methods=['post'], detail=True)
    #     更新
    def update_resource(self, request, pk):
        data = request.data.get('resource')
        print("前端的数据",data)
        Resource.objects.filter(id=pk).update(
            name=data['name'],
            url=data['url'],
            pid=data['pid']
        )
        return Response({'msg': '修改成功'})


class RoleFilter(FilterSet):
    name = django_filters.rest_framework.CharFilter(field_name='name')

    class Meta:
        model = Role
        fields = ['name']


class RoleModelView(viewsets.ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['name']

    @action(detail=False, methods=['post'])
    def get_pid_xid(self, request):
        role_id = request.data.get('xid')
        print('--------------------------------------------')
        print(request.data)
        if not request.data['pid'] == '':
            Role.objects.filter(id=role_id).update(pid_id=request.data['pid'])
            datas = Role.objects.filter(id=role_id).first()
            ser = self.get_serializer(datas)
            pid_id = datas.pid.id
            print(role_id)
            print(pid_id)
            son_list = Role.objects.get(id=role_id).resource.all()
            parent_list = Role.objects.get(id=request.data.get('pid')).resource.all()
            print(son_list)
            print(parent_list)
            res_list = []
            parent_id = []
            for i in son_list:
                res_list.append(i.id)
            for i in parent_list:
                res_list.append(i.id)
                parent_id.append({'id':i.id})
            ser_data = ser.data
            ser_data['resource'] = res_list

            return Response({"msg": 'ok', "data": ser_data, "parent_list": parent_id})
        else:
            datas = Role.objects.filter(id=role_id).first()
            ser = self.get_serializer(datas)
            pid_id = datas.pid.id
            print(role_id)
            print(pid_id)
            son_list = Role.objects.get(id=role_id).resource.all()
            parent_list = Role.objects.get(id=request.data.get('pid')).resource.all()
            print(son_list)
            print(parent_list)
            res_list = []
            parent_id = []
            for i in son_list:
                res_list.append(i.id)
            for i in parent_list:
                res_list.append(i.id)
                parent_id.append({'id':i.id})
            ser_data = ser.data
            ser_data['resource'] = res_list
            return Response({"msg": 'ok', "data": ser_data, "parent_list": parent_id})

    @action(detail=False, methods=['post'])
    def update_role_list(self, request):
        print('weolao')
        print(request.data)
        role_id = request.data.get('id')
        pid_id = request.data.get('pid')
        print('666')
        print(pid_id)

        # 更新角色基本信息
        role = Role.objects.filter(id=role_id).first()
        if role:
            role.name = request.data.get('name')
            role.pid = Role.objects.get(id=pid_id)
            role.type = request.data.get('type')
            role.save()

            # 获取父角色的资源
            parent_resource = role.pid.resource.all() if role.pid else []
            role_resource = request.data.get('resource')
            print(parent_resource)
            print('前边集成数据----后边更新数据')
            print(role_resource)

            # 计算差集
            new_resource_ids = set(role_resource) - set(parent_resource.values_list('id', flat=True))
            print('-------------------')
            print(new_resource_ids)

            # 清除原有资源并添加新的资源
            role.resource.clear()
            for resource_id in new_resource_ids:
                role.resource.add(resource_id)

            return Response({"msg": 'ok'})
        else:
            return Response({"msg": '角色不存在'}, status=400)

    @action(methods=['get'], detail=False)
    def get_role_inherit(self, request):
        role_inherit = Role.objects.filter(pid__isnull=True)
        # print(role_inherit)
        if role_inherit:
            ser = RoleSerializer(role_inherit, many=True)
            return Response({'msg': '查询父类成功', 'data': ser.data})

    @action(methods=['get'], detail=False)
    def get_role(self, request):
        role = Role.objects.filter(pid__isnull=False)
        # print(role_inherit)
        if role:
            ser = RoleSerializer(role, many=True)
            return Response({'msg': '查询子类角色成功', 'data': ser.data})

    @action(methods=['post'], detail=False)
    def add_role(self, request, *args, **kwargs):
        parent_id = request.data.get('pid')
        if parent_id:
            try:
                parent_role = Role.objects.get(id=parent_id)
            except Role.DoesNotExist:
                return Response({'msg': '父角色不存在'}, status=400)
        else:
            parent_role = None

        role = Role.objects.create(
            name=request.data['name'],
            pid=parent_role,  # 传递父角色的实例
            type=request.data['type'],
        )
        ser = RoleSerializer(role)
        parent_resource = parent_role.resource.all() if parent_role else []
        role_resource = request.data.get('resource', [])
        print('---------')
        print(parent_resource)
        # 计算差集
        if parent_role:
            new_resource_ids = set(request.data.get('resource', [])) - set(parent_resource.values_list('id', flat=True))
        else:
            new_resource_ids = set(request.data.get('resource', []))
        # 添加差集中的资源到新角色
        for resource_id in new_resource_ids:
            role.resource.add(resource_id)
        return Response({'msg': '添加成功'})

    @action(methods=['delete'], detail=True)
    def delete_role(self, request, pk):
        role = Role.objects.filter(id=pk).first()
        print(role)
        if role.type == 0:
            return Response({'msg': '不能删除根角色', "code": 400})
        else:
            role.delete()
            return Response({'msg': '删除成功', "code": 200})


#
# 互斥

class Resource_expModelView(viewsets.ModelViewSet):
    queryset = Resource_exp.objects.all()
    serializer_class = Resource_expSerializer

    @action(methods=['get'], detail=False)
    def is_simple(self, request):
        res1 = request.GET.get('res1')
        res2 = request.GET.get('res2')
        # print("---------------")
        # print(res1,res2)
        if res1 == res2:
            return Response({'msg': '不能选择相同的资源', "data": [res1, res2]})
        else:
            exists = Resource_exp.objects.filter(Q(res1=res1, res2=res2) | Q(res1=res2, res2=res1)).exists()
            if exists:
                return Response({'msg': '互斥关系已存在'})
            else:
                return Response({'msg': '可以添加数据', "data": int(res2)})


class StaffModelFilter(FilterSet):
    roleid = django_filters.rest_framework.CharFilter(field_name='roleid')
    username = django_filters.rest_framework.CharFilter(field_name = "username")
    name = django_filters.rest_framework.CharFilter(field_name = "name")
    update_time = django_filters.DateTimeFilter(field_name='update_time', lookup_expr='lte')
    class Meta:
        model = StaffModel
        fields = ['roleid', "username", "name", 'update_time']


class PageStaffModel(PageNumberPagination):
    page_size = 7
    page_size_query_param = 'page_size'
    page_query_param = "page"

class StaffModelView(viewsets.ModelViewSet):
    queryset = StaffModel.objects.all()
    serializer_class = StaffSerializer
    pagination_class = PageStaffModel
    filter_backends = [DjangoFilterBackend]
    filterset_class = StaffModelFilter

    @action(detail=False, methods=['post'])
    def login_user(self, request):
        username = request.data.get("username")
        password = request.data.get("password")
        if username is None or username == "":
            return Response({"code": 400, "msg": "用户名不能为空"})
        if password is None or password == "":
            return Response({"code": 401, "msg": "密码不能为空"})
        user = StaffModel.objects.filter(username=username, password=password).first()
        if user:
            # 查询角色资源
            users = StaffModel.objects.filter(id=user.id).first()
            # if users:
            user_res1 = list(users.roleid.resource.all())
            user_res2 = list(users.roleid.pid.resource.all())
            # 查询角色工作流
            workflows_data = WorkflowPermission.objects.filter(role_id=user.roleid)
            ser_workflow = WorkflowPermission_Ser(workflows_data, many=True)
            print("================")
            # 点击的是字段
            my_jwt = MJwt()
            token = my_jwt.jwt_encode(user.id, user.roleid.id)
            ser = ResourceSerializer(user_res1 + user_res2, many=True)
            return Response({"code": 200, "msg": "登录成功", "data1": user.id, 'menulist': ser.data, "token": token,
                             "data2": user.roleid.id})
        return Response({"code": 402, "msg": "用户名或密码错误"})

    # @action(detail=False, methods=['post'])
    # def login_user(self, request):
    #     username = request.data.get("username")
    #     print(request.data)
    #     password = request.data.get("password")
    #     print(password)
    #     if username is None or username == "":
    #         return Response({"code": 400, "msg": "用户名不能为空"})
    #     if password is None or password == "":
    #         return Response({"code": 401, "msg": "密码不能为空"})
    #     user = StaffModel.objects.filter(username=username, password=password).first()
    #     if user:
    #         datas_parent = Resource.objects.filter(pid__isnull=True)
    #         resource_list = []
    #         for i in datas_parent:
    #             resource_list.append({
    #                 'id': i.id,
    #                 'name': i.name,
    #                 'url': i.url,
    #                 'children': []
    #             })
    #         # print(resource_list)
    #         datas_son = Resource.objects.filter(pid__isnull=False)
    #         for i in datas_son:
    #             for j in resource_list:
    #                 if i.pid_id == j['id']:
    #                     j['children'].append({
    #                         'id': i.id,
    #                         'name': i.name,
    #                         'url': i.url,
    #                         'pid': i.pid_id,
    #                     })
    #         my_jwt = MJwt()
    #         token = my_jwt.jwt_encode(user.id, user.roleid.id)
    #
    #         return Response(
    #             {"code": 200, "msg": "登录成功", "data": user.id, 'menulist': resource_list, "token": token})

    # @action(methods=['get'], detail=True)
    # def get_menulist(self, request,pk):
    #     # users = Users.objects.filter(id=user).first()
    #     # user_id = request.query_params.get('user_id')
    #     # user_id = request.query_params.get('user_id')
    #     # users = Users.objects.filter(id=user_id).first()
    #     users = Users.objects.filter(id=pk).first()
    #     # if users:
    #     user_res1 = list(users.roleid.resource.all())  # 点击的是字段
    #     # print(user_res1)
    #     first_menu = []
    #     second_menu = []
    #     data_s = Resource.objects.all()
    #     ser = ResourceSerializer(user_res1, many=True)
    #     return Response({'msg': 'ok', 'menulist': ser.data})
    @action(detail=True, methods=['put'])
    def putuser(self, request, pk):
        name = request.data.get('name')
        roleid = request.data.get('roleid')
        username = request.data.get('username')
        phone = request.data.get('phone')
        update_person = request.data.get('update_person')
        avatar = request.FILES.get('avatar')
        print("=======================================")
        print(avatar)
        user = StaffModel.objects.filter(id=pk).first()
        if user:
            if avatar:
                user.avatar = avatar
                user.save()
            StaffModel.objects.filter(id=pk).update(
                name=name,
                roleid=roleid,
                username=username,
                phone=phone,
                update_person=update_person,
            )
            return Response({"message": "修改成功", })
        return Response({"message": "不做任何操作"})
    @action(detail=False, methods=['post'])
    def get_username(self, request):
        username = request.data.get('username')
        print(username)
        user_res1 = StaffModel.objects.filter(username=username).first()
        if user_res1:
            return Response({"message": "该用户名已注册", })
        return Response({"message": "该用户名未注册"})

    @action(detail=False, methods=['post'])
    def get_password(self, request):
        password = request.data.get('password')
        if not re.search(r'[^a-zA-Z0-9]', password):
            return Response({"message": "密码必须包含字母，数字，特殊字符"})
        else:
            return Response({"message": "密码格式正确"})

    @action(detail=False, methods=['post'])
    def get_phone(self, request):
        phone = request.data.get('phone')
        user_res1 = StaffModel.objects.filter(phone=phone).first()
        if not user_res1 and re.match(r'^1[3-9]\d{9}$', phone):
            return Response({"message": "手机号可用", })
        return Response({"message": "手机号已注册"})

    @action(detail=False, methods=['post'])
    def postuser(self, request):
        try:
            name = request.data.get('name')
            roleid = request.data.get('roleid')
            dept_id = request.data.get("departmentid") 
            position_id = request.data.get("positionid")
            username = request.data.get('username')
            password = request.data.get('password')
            phone = request.data.get('phone')
            update_person = request.data.get('update_person')
            avatar = request.FILES.get("avatar")

            # 获取关联的模型实例
            department = Department.objects.get(id=dept_id)
            position = Position.objects.get(id=position_id)

            # 获取最后一个staff_id
            user = StaffModel.objects.order_by('-staff_id').first()
            new_staff_id = user.staff_id + 1 if user else 100

            # 创建新用户
            new_user = StaffModel.objects.create(
                name=name,
                roleid_id=roleid,  # 这个用ID
                dept_id=department,    # 使用实例
                position=position,  # 使用实例
                username=username,
                password=password,
                phone=phone,
                update_person=update_person,
                staff_id=new_staff_id
            )

            # 如果有头像文件，保存头像
            if avatar:
                new_user.avatar = avatar
                new_user.save()

            ser = StaffSerializer(new_user)
            return Response({"message": "添加成功", "data": ser.data})

        except Exception as e:
            return Response({"message": "添加失败", "error": str(e)}, status=500)


# 用户信息
class Person_infoFilter(FilterSet):
    birth_date = django_filters.rest_framework.DateTimeFilter(field_name='birth_date', lookup_expr='lte')
    nickname = django_filters.rest_framework.CharFilter(field_name='nickname', lookup_expr="icontains")
    class Meta:
        model = PersonModel
        fields = ['birth_date', 'nickname']


class Person_infoView(viewsets.ModelViewSet):
    queryset = PersonModel.objects.all()
    serializer_class = Person_infoSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = Person_infoFilter


# 角色权限和工作流
class Role_permissionView(viewsets.ModelViewSet):
    queryset = WorkflowPermission.objects.all()
    serializer_class = WorkflowPermission_Ser
    @action(methods=['post'], detail=False)
    def add_per(self, request):
        datas = request.data
        datas_works = datas.get("works", [])
        print(datas)
        print(datas_works)

        for i in datas_works:
            print(i)
            if self.get_queryset().filter(role_id=datas['role_id'], workflow_id=i['id']).exists():
                return Response({'msg': '该角色已拥有该工作流权限，请勿重复添加'})
            else:
                data__ = self.get_queryset().create(
                    role_id=Role.objects.get(id=datas['role_id']),
                    workflow_id=Workflow.objects.get(id=i['id']),
                )

        return Response({'msg': '添加成功'})

    @action(methods=['get'], detail=True)
    def get_per(self, request, pk):
        workflows = WorkflowPermission.objects.filter(role_id=pk)
        Ser_work = WorkflowPermission_Ser(workflows, many=True)
        return Response({'msg': '查询成功', "data": Ser_work.data})


#    工作流表
class WorkFlowView(viewsets.ModelViewSet):
    queryset = Workflow.objects.all()
    serializer_class = WorkFlowSerializer

    @action(methods=['post'], detail=False)
    def add_workflow(self, request):
        datas = request.data
        print(datas)
        if self.get_queryset().filter(name=datas['name']).exists():
            return Response({'msg': '该工作流已存在，请勿重复添加'})
        else:
            data__ = self.get_queryset().create(
                name=datas['name'],
                params=datas['params'],
                status=datas["status"]
            )
        return Response({'msg': '添加成功'})


# 审批节点视图
class WorkflowApprovalNodeModelViewSet(viewsets.ModelViewSet):
    queryset = WorkflowApprovalNode.objects.all()
    serializer_class = WorkflowApprovalNodeSerializer
    # 添加审批节点表，审批人，以及审批人等级
    @action(methods=['post'], detail=False)
    def add_node(self, request):
        datas = request.data
        print(datas)
        level_map = datas.get('pos_level')
        pos_ids = datas.get('pos_id')
        workflow_id_list = datas.get('workflow_data')['works']

        for pos_id in pos_ids:
            level = level_map[str(pos_id)]
            for workflow in workflow_id_list:
                position = Position.objects.get(id=pos_id)
                workflow_obj = Workflow.objects.get(id=workflow['id'])

                # 检查数据库中是否已存在相同的记录
                if not WorkflowApprovalNode.objects.filter(
                        level=level,
                        position_id=position,
                        workflow_id=workflow_obj
                ).exists():
                    WorkflowApprovalNode.objects.create(
                        level=level,
                        position_id=position,
                        workflow_id=workflow_obj
                    )
        return Response({'msg': '添加成功'})
    # 查询工作流
    @action(methods=['post'], detail=False)
    def get_workflow_list(self, request):
        data = request.data
        print("===================")
        print(data)
        workflow_id = Workflow.objects.get(id=data['id'])
        print("++++++++++++++++++")
        print(workflow_id)
        node_list = self.get_queryset().filter(workflow_id=workflow_id,).all().order_by('id')
        data_one = WorkflowApprovalNode.objects.filter(workflow_id=workflow_id).order_by("id").first()
        next_audit = StaffModel.objects.filter(dept_id=data_one.position_id.department,
                                               position=data_one.position_id).first()
        next_audit_ser = StaffSerializer(next_audit)
        res_list = []
        for i in node_list:
            print({"level": i.level, "name": i.position_id})
            pos_data = StaffModel.objects.get(position=i.position_id)
            print(pos_data.name)
            res_list.append({"level": i.level, "name": pos_data.name})
        # print(ser.data)
        # return Response({"msg":'ok',"data":ser.data})
        return Response({'msg': '查询成功', "data": res_list, "next_audit": next_audit_ser.data["id"]})


# 部门视图
class DepartmentModelViewSet(viewsets.ModelViewSet):
    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer


# 职位视图
class PositionModelViewSet(viewsets.ModelViewSet):
    queryset = Position.objects.all()
    serializer_class = PositionSerializer

    @action(methods=['post'], detail=False)
    def get_dep_position(self, request):
        dep_id = request.data.get('dep_id')
        print(dep_id)
        data = self.get_queryset().filter(department=Department.objects.get(id=dep_id)).all()
        ser = PositionSerializer(data, many=True)
        return Response({'msg': '查询成功', 'data': ser.data})
        # return Response({'msg': '查询成功'})


# 任务查询
# class TaskFilter(FilterSet):
#     staffid = django_filters.rest_framework.CharFilter(field_name='staffid')
#     class Meta:
#         model = Task
#         fields = ["staffid"]
# 任务表
class TaskModelViewSet(viewsets.ModelViewSet):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    # filterset_class = TaskFilter
    # filter_backends = [DjangoFilterBackend]
    # 调用工具
    # 添加任务表（员工在OA审批中提交申请）
    @action(methods=["post"], detail=False)
    def add_task(self, request):
        print(request.data)
        # 前端传回数据
        name = request.data.get("name")
        params = request.data.get("params")
        workflow_id = int(request.data.get("workflow_id"))
        staffid = int(request.data.get("staffid"))
        next_audit = int(request.data.get("next_audit"))
        level = 1
        task_data = {
            'name': name,
            'params': params,
            'workflow_id': workflow_id,
            'staffid': staffid,  # 确保键名与模型中的字段名匹配
            'next_audit': next_audit,
            'level': level
        }
        print(task_data)
        # 将字典转化为JSON字符串，传入工具
        taskid = audit_workflow("提交任务，请根据提供的数据给我返回一个任务id，只返回数字:" + json.dumps(task_data))
        print(str(taskid))
        res=audit_workflow("分配审核人，任务id是,请只给我返回下一个审批人的id，只返回数字："+str(taskid))
        return Response({"msg": "添加成功"})

    @action(methods=['post'], detail=False)
    def get_task_list(self, request, *args, **kwargs):
        staff_id = request.data.get('id')
        print("===========", staff_id)
        print('-----------------上')
        print(staff_id)
        data = self.get_queryset().filter(next_audit=staff_id).all()
        print(data)
        ser = TaskSerializer(data, many=True)
        return Response({'msg': '查询成功', 'data': ser.data})
#    员工查看任务表申请记录
    @action(detail=False, methods=['get'])
    def get_stafftask_status(self, request):
        staffid = request.query_params.get('staffid')
        stafftask = Task.objects.filter(staffid=staffid).all()
        ser= TaskSerializer(stafftask,many=True)
        if stafftask:
            return Response({'code': 200, 'msg': '查询成功', 'data': ser.data})
        else:
            return Response({'code': 400, 'msg': '您还没有任何申请'})
# 审批记录表
class Approval_RecordView(viewsets.ModelViewSet):
    queryset = Approval_Record.objects.all()
    serializer_class = Approval_RecordSerializer
    @action(methods=['post'], detail=False)
    def add_approval_record(self, request):
        res=audit_workflow("更新审核结果,数据为:"+json.dumps(request.data))
        return Response({"msg": "数据更新成功","data":res})
    # @action(methods=['post'], detail=False)
    # def get_audit_record(self, request):
    #     task_id = request.data.get('task_id')
    #     print(task_id)
    #     data = self.get_queryset().filter(workTask=Task.objects.get(id=task_id)).all()
    #     ser = Approval_RecordSer(data, many=True)
    #     res_list = []
    #     for i in ser.data:
    #         res_list.append(i)
    #     next_audit = Approval_Record.objects.filter(workTask=Task.objects.get(id=task_id)).order_by('-id')[0]
    @action(methods=["get"],detail=False)
    def get_task_record(self,request):
        task_id = request.query_params.get('task_id')
        data = self.get_queryset().filter(task_id=task_id).all()
        ser = Approval_RecordSerializer(data, many=True)
        res_list = []
        for i in ser.data:
            res_list.append(i)
        return Response({"msg": "数据获取成功","data":res_list})
